//
//  NSObject+MolonAPI.m
//
//  Created by Molon on 13-9-30.
//  Copyright (c) 2013年 Molon. All rights reserved.
//

#import "NSObject+MolonAPI.h"
#import "MolonRequestHelper.h"
#import "MLDataHelper.h"
#import "Model.h"
#import "ModelArray.h"
#import "MLKitDebug.h"
#import "MolonAPI.h"

#import <objc/runtime.h>

static char careForRequestHelperNotificationObserverKey;

@protocol CareForRequestHelperNotificationObserverDelegate <NSObject>

- (void)updatedCareForRequestHelper:(MolonRequestHelper*)requestHelper andBindObject:(id)bindObject;

@end

//存储绑定的通知名字，以便于自动移除观察者
@interface CareForRequestHelperNotificationObserver : NSObject

@property (nonatomic, strong) NSMutableArray *careForRequestHelperNotificationNames;

@property (nonatomic, weak) id<CareForRequestHelperNotificationObserverDelegate> delegate;

@end

@implementation CareForRequestHelperNotificationObserver

- (void)dealloc
{
    //移除观察者
    if (self.careForRequestHelperNotificationNames.count>0) {
        //因为都释放了，所以直接删除完所有通知即可，careForRequestHelperNotificationNames是用来防止重复添加
        [[NSNotificationCenter defaultCenter]removeObserver:self];
//        for (NSString *notificationName in self.careForRequestHelperNotificationNames) {
//            [[NSNotificationCenter defaultCenter]removeObserver:self name:notificationName object:nil];
//        }
    }
}

- (void)careForRequestHelperClass:(Class)helperClass
{
    NSString *notificationName = [NSString stringWithFormat:@"%@%@",MolonAPIRequestHelperStateUpdatedNotificationNamePrefix,NSStringFromClass(helperClass)];
    if ([self.careForRequestHelperNotificationNames containsObject:notificationName]) {
        return;
    }
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(careForRequestHelperNotificationCallback:) name:notificationName object:nil];
    
    //懒加载记录集
    if (!self.careForRequestHelperNotificationNames) {
        self.careForRequestHelperNotificationNames = [NSMutableArray array];
    }
    
    //记录下
    [self.careForRequestHelperNotificationNames addObject:notificationName];
}

#pragma mark - notification callback
- (void)careForRequestHelperNotificationCallback:(NSNotification*)notification
{
    if (self.delegate&&[self.delegate respondsToSelector:@selector(updatedCareForRequestHelper:andBindObject:)]) {
        MolonRequestHelper *helper = notification.userInfo[@"requestHelper"];
        id bindObject = notification.userInfo[@"bindObject"];
        
        [self.delegate updatedCareForRequestHelper:helper andBindObject:bindObject];
    }
}

@end

@interface NSObject()

@property (nonatomic, strong) CareForRequestHelperNotificationObserver *careForRequestHelperNotificationObserver;

@end

@implementation NSObject (MolonAPI)

#pragma mark - MolonAPI call
- (void)ml_nsobject_requestSucceeded:(MolonRequestHelper *)requestHelper
{
    [self mustExecuteAfterRequestCompleted:requestHelper];
    [self requestSucceeded:requestHelper];
}

- (void)ml_nsobject_requestFailed:(MolonRequestHelper *)requestHelper
{
    [self mustExecuteAfterRequestCompleted:requestHelper];
    [self requestFailed:requestHelper];
}

- (void)ml_nsobject_requestError:(MolonRequestHelper *)requestHelper
{
    [self mustExecuteAfterRequestCompleted:requestHelper];
    [self requestError:requestHelper];
}

- (void)ml_nsobject_cachePreloaded:(MolonRequestHelper *)requestHelper
{
    [self cachePreloaded:requestHelper];
}

#pragma mark - override
- (void)mustExecuteAfterRequestCompleted:(MolonRequestHelper *)requestHelper;
{
    [[MolonAPI sharedInstance].delegate commonMustExecuteAfterRequestCompleted:requestHelper bindObject:self];
}

- (void)requestSucceeded:(MolonRequestHelper *)requestHelper
{
//    [self doesNotRecognizeSelector:_cmd];
}

- (void)requestFailed:(MolonRequestHelper *)requestHelper
{
    [[MolonAPI sharedInstance].delegate commonAfterRequestFailedWithHelper:requestHelper bindObject:self];
}

- (void)requestError:(MolonRequestHelper *)requestHelper
{
    [self requestFailed:requestHelper];
}

- (void)cachePreloaded:(MolonRequestHelper *)requestHelper
{
    
}

#pragma mark - care for
- (void)setCareForRequestHelperNotificationObserver:(CareForRequestHelperNotificationObserver *)observer
{
    static NSString * key = @"careForRequestHelperNotificationObserver";
    
    [self willChangeValueForKey:key];
    objc_setAssociatedObject(self, &careForRequestHelperNotificationObserverKey, observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self didChangeValueForKey:key];
}

- (CareForRequestHelperNotificationObserver *)careForRequestHelperNotificationObserver
{
    return objc_getAssociatedObject(self, &careForRequestHelperNotificationObserverKey);
}

#warning 此机制暂时不支持子类监视 dont support subclass observer  
- (void)careForRequestHelperClass:(Class)helperClass
{
    if (!self.careForRequestHelperNotificationObserver) {
        self.careForRequestHelperNotificationObserver = [CareForRequestHelperNotificationObserver new];
        self.careForRequestHelperNotificationObserver.delegate = (id<CareForRequestHelperNotificationObserverDelegate>)self;
    }
    
    [self.careForRequestHelperNotificationObserver careForRequestHelperClass:helperClass];
}

- (void)updatedCareForRequestHelper:(MolonRequestHelper*)requestHelper andBindObject:(id)bindObject
{
    [self doesNotRecognizeSelector:_cmd];
}

@end
